package manager

import (
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"github.com/gin-gonic/gin"
	"net"
	"strconv"
	"tadmin/models"
	"tadmin/models/dto"
	"tadmin/pkg/ginx"
	"tadmin/service"
	"time"
)

var sensorService = &service.SensorService{}

type SensorApi struct{}

//func (sensorApi *SensorApi) Add(c *gin.Context) {
//	var addDto dto.WorkerAddDto
//	c.ShouldBindJSON(&addDto)
//	err := workerService.Add(addDto)
//	ginx.Result(c, nil, err)
//}

func (sensorApi *SensorApi) Query(c *gin.Context) {
	var queryDto dto.SensorQueryDto
	c.ShouldBindJSON(&queryDto)

	var queryReq = service.QuerySensorReq{
		Name:          queryDto.Name,
		WorkUnit:      queryDto.WorkUnit,
		WorkPlace:     queryDto.WorkPlace,
		CardNo:        queryDto.CardNo,
		GlobalSteelNo: queryDto.GlobalSteelNo,
		ShiftSteelNo:  queryDto.ShiftSteelNo,
		AnchorBoltNo:  queryDto.AnchorBoltNo,
		Pressure:      queryDto.Pressure,
	}
	if queryDto.StartTime != 0 {
		queryReq.StartTime = time.UnixMilli(queryDto.StartTime)
	}
	if queryDto.EndTime != 0 {
		queryReq.EndTime = time.UnixMilli(queryDto.EndTime)
	}

	list, err := sensorService.Query(&queryReq)
	voList := SensorItemToSensorVOList(list)

	ginx.Result(c, gin.H{
		"list": voList,
	}, err)
}

func SensorItemToSensorVOList(sensorItems []models.SensorItem) []dto.SensorVO {
	var sensorVOs []dto.SensorVO

	for _, item := range sensorItems {
		sensorVO := dto.SensorVO{
			Name:          item.Name,
			WorkUnit:      item.WorkUnit,
			WorkPlace:     item.WorkPlace,
			CardNo:        item.CardNo,
			GlobalSteelNo: item.GlobalSteelNo,
			ShiftSteelNo:  item.ShiftSteelNo,
			AnchorBoltNo:  item.AnchorBoltNo,
			Pressure:      item.Pressure,
			GmtCreate:     uint64(item.GmtCreate.UnixMilli()),
			GmtModify:     uint64(item.GmtModify.UnixMilli()),
		}
		sensorVOs = append(sensorVOs, sensorVO)
	}

	return sensorVOs
}

func Init() {
	// 1. 修改为UDP监听
	listener, err := net.ListenUDP("udp", &net.UDPAddr{Port: 8080})
	if err != nil {
		fmt.Println(err)
		panic(err)
	}

	fmt.Println("Server is listening on port 8080...")
	go func() {
		defer listener.Close()
		for {
			handleUDPConnection(listener) // 直接处理UDP连接
		}
	}()
}

func handleUDPConnection(listener *net.UDPConn) {
	buf := make([]byte, 16)
	n, _, err := listener.ReadFromUDP(buf)
	if err != nil {
		fmt.Printf("Error reading from UDP connection: %v\n", err)
		return
	}

	if n != 16 {
		fmt.Printf("Received packet with unexpected length (%d bytes)\n", n)
		return
	}

	sensorAdd, err := convertToAddReq(buf)

	if err != nil {
		fmt.Println("invalid sensor data structure")
		return
	}

	err = sensorService.Add(sensorAdd)
}

func convertToAddReq(data []byte) (*dto.SensorAddDto, error) {
	dto := &dto.SensorAddDto{}

	// CardNo: 前8个字节转为16进制
	cardNoHex := hex.EncodeToString(data[:8])
	dto.CardNo = cardNoHex

	// 其他字段每两个字节转为10进制字符串
	dto.GlobalSteelNo = strconv.Itoa(int(binary.BigEndian.Uint16(data[8:10])))
	dto.ShiftSteelNo = strconv.Itoa(int(binary.BigEndian.Uint16(data[10:12])))
	dto.AnchorBoltNo = strconv.Itoa(int(binary.BigEndian.Uint16(data[12:14])))
	dto.Pressure = strconv.Itoa(int(binary.BigEndian.Uint16(data[14:16])))

	return dto, nil
}
